//package com.alibaba.citrus.cr.platform.enhance.facade.service.diff.sap;
//
//import java.util.ArrayList;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//import java.util.Objects;
//import java.util.function.Function;
//import java.util.stream.Collectors;
//
//import javax.annotation.Resource;
//
//import com.alibaba.acm.shaded.com.google.common.collect.Lists;
//import com.alibaba.citrus.common.pair.Pair;
//import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
//import com.alibaba.citrus.cr.common.exception.FacadeException;
//import com.alibaba.citrus.cr.common.util.SapAndCrmFieldDealUtils;
//import com.alibaba.citrus.cr.platform.enhance.facade.service.diff.common.DiffCheckRequest;
//import com.alibaba.citrus.cr.platform.enhance.facade.service.diff.common.constant.DiffResultStatus;
//import com.alibaba.citrus.cr.platform.enhance.facade.service.diff.common.constant.DiffTypeEnum;
//import com.alibaba.citrus.cr.platform.enhance.functions.diff.common.constant.DiffStrategyRouteDict;
//import com.alibaba.citrus.cr.platform.enhance.functions.diff.common.dataParser.DataParserManager;
//import com.alibaba.citrus.cr.platform.enhance.functions.diff.common.router.DiffCheckProcessor;
//import com.alibaba.citrus.cr.platform.enhance.functions.diff.common.router.DiffStrategyRoute;
//import com.alibaba.citrus.cr.platform.enhance.functions.diff.common.template.StandardTemplateDiff;
//import com.alibaba.citrus.cr.platform.enhance.functions.diff.sap.template.Sap017DetailStandardTemplate;
//import com.alibaba.citrus.cr.platform.enhance.functions.diff.sap.template.Sap017SDOStandardTemplate;
//import com.alibaba.citrus.cr.platform.enhance.repository.ConsignmentOrderRepository;
//import com.alibaba.citrus.cr.platform.enhance.repository.DiffErrorRepository;
//import com.alibaba.citrus.cr.platform.enhance.repository.model.diff.ConsignmentOrder.ConsignmentOrderDTO;
//import com.alibaba.citrus.cr.platform.enhance.repository.model.diff.ConsignmentOrder.ConsignmentOrderLineDTO;
//import com.alibaba.citrus.cr.platform.enhance.repository.model.diff.common.*;
//import com.alibaba.citrus.trail.log.LogEntry;
//import com.alibaba.cz.base.tool.log.Log;
//import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.JSONObject;
//import com.alibaba.lattice2.epoch.sdk.model.Result;
//import com.alibaba.nacos.common.utils.MapUtils;
//
//import com.epoch.app.otsapplicationadaptersdk.sap.MnSapIf017Detail;
//import com.epoch.app.otsapplicationadaptersdk.sap.MnSapIf017Request;
//import com.epoch.app.otsapplicationadaptersdk.sap.MnSapIf017SDO;
//import com.epoch.app.crplatformenhance.model.dto.Sap017DiffRequest;
//import com.epoch.app.crplatformenhance.sap017diffcheck.dto.DiffCheckBySapDataRequest;
//import com.epoch.app.crplatformenhance.sap017diffcheck.service.Sap017DiffCheckService;
//import org.apache.commons.collections4.CollectionUtils;
//import org.apache.commons.lang.StringUtils;
//import org.springframework.context.annotation.Primary;
//import org.springframework.stereotype.Service;
//
///**
// * @author: qiaojiange
// * @create: 2022/01/23
// * @Description sap 017 对账
// */
//@Service
//@Primary
//public class Sap017DiffCheckServiceImpl extends AbstractDiffCheck implements Sap017DiffCheckService {
//    /**
//     * 日志
//     */
//    private Log log = Log.getLogger(SapDiffCheckServiceImpl.class);
//    /**
//     * 标准对账模板
//     */
//    @Resource
//    private StandardTemplateDiff standardTemplateDiff;
//
//    /**
//     * 数据解析器管理类
//     */
//    @Resource
//    private DataParserManager dataParserManager;
//
//    /**
//     * 对账策略路由
//     */
//    @Resource
//    private DiffStrategyRoute diffStrategyRoute;
//
//    /**
//     * 差错资源类
//     */
//    @Resource
//    private DiffErrorRepository diffErrorRepository;
//
//    @Resource
//    private ConsignmentOrderRepository consignmentOrderRepository;
//
//    @Override
//    @FacadeInvoker
//    public Result<String> diffCheck(Sap017DiffRequest sap017DiffRequest) {
//        checkParam(sap017DiffRequest);
//        super.doTraverse(sap017DiffRequest.getCondition(),sap017DiffRequest.getStartDate(),
//                sap017DiffRequest.getEndDate());
//        return Result.success("ture");
//    }
//
//    @Override
//    void doHandlerLog(Pair<Integer, List<LogEntry>> pair) {
//        List<DiffErrorDTO> diffErrorDTOList = new ArrayList<>();
//        pair.right().forEach(logEntry -> {
//            if (MapUtils.isNotEmpty(logEntry.contents())) {
//                String sapMsg = logEntry.contents().get("input");
//                log.info("sapMsg={}", sapMsg);
//                JSONObject jsonObject = JSON.parseObject(sapMsg);
//                String data = jsonObject.getString("body").trim();
//                log.info("data={}", data);
//                MnSapIf017Request sapIf017Request = JSON.parseObject(data, MnSapIf017Request.class);
//                List<MnSapIf017SDO> sapIf017SDOList = sapIf017Request.getData();
//                if (CollectionUtils.isNotEmpty(sapIf017SDOList)) {
//                    for (MnSapIf017SDO sapIf017SDO : sapIf017SDOList) {
//                        if (Objects.isNull(sapIf017SDO)) {
//                            continue;
//                        }
//
//                        List<DiffErrorDTO> diffErrorDTOList1 = sap017Diff(sapIf017SDO);
//                        if (CollectionUtils.isNotEmpty(diffErrorDTOList1)) {
//                            diffErrorDTOList.addAll(diffErrorDTOList1);
//                        }
//                    }
//                }
//            }
//        });
//
//        if (CollectionUtils.isNotEmpty(diffErrorDTOList)) {
//            diffErrorRepository.batchSaveDiffErrorList(diffErrorDTOList);
//        }
//    }
//
//
//    /**
//     * sap017 对账
//     *
//     * @param sapIf017SDO SAP017 数据
//     * @return
//     */
//    private List<DiffErrorDTO> sap017Diff(MnSapIf017SDO sapIf017SDO) {
//        List<DiffErrorDTO> diffErrorDTOList = new ArrayList<>();
//        try {
//            //1. 数据抽取
//            Map<String, FieldLineDTO> sapIf017SDOMap = dataParserManager.parse(sapIf017SDO);
//
//            //2. 和标准模板进行对比，检查是否缺的问题。 缺失有两个问题： a. 字段缺失， b. 数值缺失
//            standardTemplateDiff.check(Sap017SDOStandardTemplate.obtainTemplateFieldSet(),
//                    sapIf017SDOMap, Sap017SDOStandardTemplate.obtainIgnoreFieldSet());
//
//            //3. 获取交货单
//            Result<ConsignmentOrderDTO> consignmentOrderDTOResult = consignmentOrderRepository.queryBySap(sapIf017SDO);
//            if (!consignmentOrderDTOResult.isSuccess()) {
//                //埋点
//                log.error("Sap017DiffCheckServiceImpl#sap017DiffCheck_fail");
//                log.error("未查询到交货单");
//                DiffErrorDTO diffErrorDto = buildDiffErrorDTO(sapIf017SDO, sapIf017SDOMap,
//                        null, "未查询到ots侧交货单信息");
//                diffErrorDTOList.add(diffErrorDto);
//                return diffErrorDTOList;
//            }
//            ConsignmentOrderDTO consignmentOrderDTO = consignmentOrderDTOResult.getResult();
//            //4. 从交货单上抽取数据
//            Map<String, FieldLineDTO> consignmentOrderDataMap = dataParserManager.parse(consignmentOrderDTO);
//            //5. 和标准模板进行对比，检查是否缺的问题。
//            standardTemplateDiff.check(Sap017SDOStandardTemplate.obtainTemplateFieldSet(), consignmentOrderDataMap,
//                    Sap017SDOStandardTemplate.obtainIgnoreFieldSet());
//
//            //6. 对账
//            DiffCheckRequest diffCheckRequest = buildDiffCheckRequest(sapIf017SDOMap, consignmentOrderDataMap);
//            DiffCheckProcessor diffCheckProcessor = diffStrategyRoute.obtainProcessor(diffCheckRequest);
//            Result<String> diffResult = diffCheckProcessor.diff(diffCheckRequest);
//            if (!diffResult.isSuccess()) {
//                //埋点
//                log.error("Sap017DiffCheckServiceImpl#sap017DiffCheck_fail");
//                DiffErrorDTO diffErrorDto = buildDiffErrorDTO(sapIf017SDO, sapIf017SDOMap,
//                        consignmentOrderDataMap, diffResult.getMessage());
//                diffErrorDTOList.add(diffErrorDto);
//            }
//
//            List<MnSapIf017Detail> sapIf017DetailList = sapIf017SDO.getItems();
//            if (CollectionUtils.isNotEmpty(sapIf017DetailList)) {
//                Map<String, ConsignmentOrderLineDTO> map = new HashMap<>();
//                Result<List<ConsignmentOrderLineDTO>> consignmentOrderLineList = consignmentOrderRepository.queryConsignmentOrderLine("" + consignmentOrderDTO.getId());
//                if (consignmentOrderLineList.isSuccess()
//                        && CollectionUtils.isNotEmpty(consignmentOrderLineList.getResult())) {
//                    map = consignmentOrderLineList.getResult().stream().collect(Collectors.toMap(ConsignmentOrderLineDTO::getOuterOrderLineId,
//                            Function.identity()));
//                }
//
//                List<DiffErrorDTO> subDiffErrorDTOList = sap017DetailDiffCheck(sapIf017SDO.getDeliveryOrderId(), sapIf017DetailList, map);
//                if (CollectionUtils.isNotEmpty(subDiffErrorDTOList)) {
//                    diffErrorDTOList.addAll(subDiffErrorDTOList);
//                }
//            }
//        } catch (Exception e) {
//            //埋点
//            log.error("Sap017DiffCheckServiceImpl#sap017DiffCheck_fail");
//            log.error("sap017主单对账出错了", e);
//            DiffErrorDTO diffErrorDto = buildDiffErrorDTO(sapIf017SDO, null,
//                    null, "对账出异常了！");
//            diffErrorDTOList.add(diffErrorDto);
//        }
//        return diffErrorDTOList;
//    }
//
//    /**
//     * 构建差错记录对象
//     *
//     * @param sapIf017SDO             SAP017 主单
//     * @param sapIf017SDOMap          SAP017 字段映射
//     * @param consignmentOrderDataMap 交货单映射
//     * @param result                  差错
//     * @return 差错对象
//     */
//    private DiffErrorDTO buildDiffErrorDTO(MnSapIf017SDO sapIf017SDO, Map<String, FieldLineDTO> sapIf017SDOMap,
//                                           Map<String, FieldLineDTO> consignmentOrderDataMap, String result) {
//
//        Map<String, String> map = new HashMap<>();
//        map.put("baseLineData", JSON.toJSONString(sapIf017SDO));
//
//        //1. 封装差错记录
//        DiffErrorDTO diffErrorDto = DiffErrorDTO.builder()
//                .diffType(DiffTypeEnum.SAP017_DIFF_CONSIGNMENT_ORDER.getDiffType())
//                //业务流程描述
//                .diffDesc(DiffTypeEnum.SAP017_DIFF_CONSIGNMENT_ORDER.getDiffDesc())
//                //对账结果描述
//                .result(result)
//                //存的是交货单 ID
//                .mainOrderId(sapIf017SDO.getDeliveryOrderId())
//                .diffData1(MapUtils.isNotEmpty(sapIf017SDOMap) ? JSON.toJSONString(sapIf017SDOMap) : null)
//                .diffData2(MapUtils.isNotEmpty(sapIf017SDOMap) ? JSON.toJSONString(consignmentOrderDataMap) : null)
//                .strategyRoute(DiffStrategyRouteDict.SAP017_DIFF_CONSIGNMENT_ORDER.getStrategyCode())
//                .features(JSON.toJSONString(map))
//                .status(DiffResultStatus.FAIL.getStatus()).build();
//        return diffErrorDto;
//    }
//
//    /**
//     * 构建对账请求
//     *
//     * @param sapIf017SDOMap          SAP017 主单映射
//     * @param consignmentOrderDataMap 交货单字段映射
//     * @return
//     */
//    private DiffCheckRequest buildDiffCheckRequest(Map<String, FieldLineDTO> sapIf017SDOMap, Map<String, FieldLineDTO> consignmentOrderDataMap) {
//        DiffCheckRequest diffCheckRequest = new DiffCheckRequest();
//        //对账类型
//        diffCheckRequest.setDiffType(DiffTypeEnum.SAP017_DIFF_CONSIGNMENT_ORDER.getDiffType());
//        //对账类型描述（就是业务流程描述）
//        diffCheckRequest.setDiffDesc(DiffTypeEnum.SAP017_DIFF_CONSIGNMENT_ORDER.getDiffDesc());
//        //策略路由
//        diffCheckRequest.setStrategyRoute(DiffStrategyRouteDict.SAP017_DIFF_CONSIGNMENT_ORDER.getStrategyCode());
//        //基准数据，key 为标准字段
//        diffCheckRequest.setBaseLineDataMap(sapIf017SDOMap);
//        //被对账数据
//        diffCheckRequest.setDiffDataMap(consignmentOrderDataMap);
//        return diffCheckRequest;
//    }
//
//    /**
//     * SAP017子单对账
//     *
//     * @param consignmentOrderId
//     * @param sapIf017DetailList SAP 子单列表
//     * @param map
//     * @return
//     */
//    private List<DiffErrorDTO> sap017DetailDiffCheck(String consignmentOrderId, List<MnSapIf017Detail> sapIf017DetailList, Map<String, ConsignmentOrderLineDTO> map) {
//        List<DiffErrorDTO> diffErrorDTOList = Lists.newArrayList();
//        for (MnSapIf017Detail sapIf017Detail : sapIf017DetailList) {
//            try {
//                Map<String, FieldLineDTO> sapIf017DetailDataMap = dataParserManager.parse(sapIf017Detail);
//                standardTemplateDiff.check(Sap017DetailStandardTemplate.obtainTemplateFieldSet(), sapIf017DetailDataMap,
//                        Sap017DetailStandardTemplate.obtainIgnoreFieldSet());
//                //3. 获取交货子单
//                ConsignmentOrderLineDTO consignmentOrderLineDTO = map.get(SapAndCrmFieldDealUtils.generateIdField(sapIf017Detail.getOrderLineId()));
//                //4. 从交货子单上抽取数据
//                Map<String, FieldLineDTO> consignmentOrderLineDataMap = dataParserManager.parse(consignmentOrderLineDTO);
//                //5. 和标准模板进行对比，检查是否缺的问题。
//                Result<String> checkResult = standardTemplateDiff.check(Sap017DetailStandardTemplate.obtainTemplateFieldSet(), consignmentOrderLineDataMap,
//                        Sap017DetailStandardTemplate.obtainIgnoreFieldSet());
//                if (!checkResult.isSuccess()) {
//                    log.error("Sap017DiffCheckServiceImpl#sap017DetailDiffCheck_fail");
//                    DiffErrorDTO diffErrorDTO = buildDetailDiffErrorDTO(consignmentOrderId, sapIf017Detail,
//                            sapIf017DetailDataMap, consignmentOrderLineDataMap, checkResult.getMessage());
//                    diffErrorDTOList.add(diffErrorDTO);
//                    continue;
//                }
//                //6. 对账
//                DiffCheckRequest detailDiffCheckRequest = buildDetailDiffCheckRequest(sapIf017DetailDataMap, consignmentOrderLineDataMap);
//                DiffCheckProcessor diffCheckProcessor = diffStrategyRoute.obtainProcessor(detailDiffCheckRequest);
//
//                Result<String> diffResult = diffCheckProcessor.diff(detailDiffCheckRequest);
//                if (!diffResult.isSuccess()) {
//                    //埋点
//                    log.error("Sap017DiffCheckServiceImpl#sap017DetailDiffCheck_fail");
//                    DiffErrorDTO diffErrorDTO = buildDetailDiffErrorDTO(consignmentOrderId, sapIf017Detail,
//                            sapIf017DetailDataMap, consignmentOrderLineDataMap, diffResult.getMessage());
//                    diffErrorDTOList.add(diffErrorDTO);
//                }
//            } catch (Exception e) {
//                //埋点
//                log.error("Sap017DiffCheckServiceImpl#sap017DetailDiffCheck_fail");
//                log.error("sap017子单对账出错了", e);
//                DiffErrorDTO diffErrorDTO = buildDetailDiffErrorDTO(consignmentOrderId, sapIf017Detail,
//                        null, null, "对账出异常了！");
//                diffErrorDTOList.add(diffErrorDTO);
//            }
//        }
//        return diffErrorDTOList;
//    }
//
//    /**
//     * 构建子单的差错记录
//     */
//    private DiffErrorDTO buildDetailDiffErrorDTO(String consignmentOrderId, MnSapIf017Detail sapIf017Detail, Map<String, FieldLineDTO> sapIf017DetailDataMap,
//                                                 Map<String, FieldLineDTO> consignmentOrderLineDataMap, String result) {
//        Map<String, String> map = new HashMap<>();
//        map.put("baseLineData", JSON.toJSONString(sapIf017Detail));
//
//        //1. 封装差错记录
//        DiffErrorDTO diffErrorDto = DiffErrorDTO.builder()
//                .diffType(DiffTypeEnum.SAP017_DETAIL_DIFF_CONSIGNMENT_ORDER_LINE.getDiffType())
//                //业务流程描述
//                .diffDesc(DiffTypeEnum.SAP017_DETAIL_DIFF_CONSIGNMENT_ORDER_LINE.getDiffDesc())
//                //对账结果描述
//                .result(result)
//                //交货单 ID
//                .mainOrderId(consignmentOrderId)
//                //交货子单 ID
//                .subOrderId(sapIf017Detail.getOrderLineId())
//                //基准数据
//                .diffData1(MapUtils.isNotEmpty(sapIf017DetailDataMap) ? JSON.toJSONString(sapIf017DetailDataMap) : null)
//                .diffData2(MapUtils.isNotEmpty(consignmentOrderLineDataMap) ? JSON.toJSONString(consignmentOrderLineDataMap) : null)
//                .strategyRoute(DiffStrategyRouteDict.SAP017_DETAIL_DIFF_CONSIGNMENT_ORDER_LINE.getStrategyCode())
//                .features(JSON.toJSONString(map))
//                .status(DiffResultStatus.FAIL.getStatus()).build();
//        return diffErrorDto;
//    }
//
//    /**
//     * 构建子单对账请求
//     *
//     * @param sapIf017DetailDataMap       子单请求
//     * @param consignmentOrderLineDataMap 交货子单字段列表
//     * @return 构建对账请求
//     */
//    private DiffCheckRequest buildDetailDiffCheckRequest(Map<String, FieldLineDTO> sapIf017DetailDataMap, Map<String, FieldLineDTO> consignmentOrderLineDataMap) {
//        DiffCheckRequest diffCheckRequest = new DiffCheckRequest();
//        //对账类型
//        diffCheckRequest.setDiffType(DiffTypeEnum.SAP017_DETAIL_DIFF_CONSIGNMENT_ORDER_LINE.getDiffType());
//        //对账类型描述（就是业务流程描述）
//        diffCheckRequest.setDiffDesc(DiffTypeEnum.SAP017_DETAIL_DIFF_CONSIGNMENT_ORDER_LINE.getDiffDesc());
//        //策略路由
//        diffCheckRequest.setStrategyRoute(DiffStrategyRouteDict.SAP017_DETAIL_DIFF_CONSIGNMENT_ORDER_LINE.getStrategyCode());
//        //基准数据，key 为标准字段
//        diffCheckRequest.setBaseLineDataMap(MapUtils.isNotEmpty(sapIf017DetailDataMap) ? sapIf017DetailDataMap : null);
//        //被对账数据
//        diffCheckRequest.setDiffDataMap(MapUtils.isNotEmpty(consignmentOrderLineDataMap) ? consignmentOrderLineDataMap : null);
//        return diffCheckRequest;
//    }
//
//    /**
//     * 通过 SAP 报文进行对账, 该方法是为了提供给页面上进行手动对账使用
//     *
//     * @param diffCheckBySapDataRequest SAP 报文对账请求
//     * @return 对账结果
//     */
//    @FacadeInvoker
//    public Result<String> diffCheckBySapData(DiffCheckBySapDataRequest diffCheckBySapDataRequest) {
//        String sap017Data = diffCheckBySapDataRequest.getSap017JsonData();
//        MnSapIf017SDO sapIf017SDO = JSON.parseObject(sap017Data, MnSapIf017SDO.class);
//        List<DiffErrorDTO> diffErrorDTOList = sap017Diff(sapIf017SDO);
//        if (CollectionUtils.isEmpty(diffErrorDTOList)) {
//            return Result.success("对账完毕，数据一致！");
//        } else {
//            return Result.fail("", JSON.toJSONString(diffErrorDTOList));
//        }
//    }
//
//    /**
//     * 校验参数
//     *
//     * @param sap017DiffRequest SAP 017请求
//     */
//    private void checkParam(Sap017DiffRequest sap017DiffRequest) {
//        if (Objects.isNull(sap017DiffRequest)) {
//            throw new FacadeException("OTS-13-001-00-16-003");
//        }
//
//        if (Objects.isNull(sap017DiffRequest.getStartDate())) {
//            throw new FacadeException("OTS-13-001-00-16-004");
//        }
//
//        if (Objects.isNull(sap017DiffRequest.getEndDate())) {
//            throw new FacadeException("OTS-13-001-00-16-005");
//        }
//
//        if (StringUtils.isBlank(sap017DiffRequest.getCondition())) {
//            throw new FacadeException("OTS-13-001-00-16-011");
//        }
//    }
//
//}
